<template>
	<div :class="['search', isWithin && 'is-within']" ref="rootElement">
		<div class="trigger">
			<form class="form" @submit.prevent>
				<input
					ref="searchElement"
					name="search"
					class="input"
					type="text"
					autocomplete="off"
					accesskey="s"
					maxlength="100"
					x-webkit-speech="zh-CN"
					x-webkit-grammar="builtin:translate"
					v-model="searchValue"
					placeholder="......"
					@keypress.stop.prevent.enter="searchEnter"
				/>
			</form>
			<UIIcon icon="search" @click="searchTag(searchValue)"></UIIcon>
		</div>
		
		<transition name="content">
			<div v-show="!hideContent && isWithin" class="content">
				<div v-show="matchedDefinedTags.length" class="match">
					<p class="match-title">
						相关词条
					</p>
					<ul class="match-list">
						<li v-for="match in matchedDefinedTags" :key="match" class="match-item" @click="searchTag(match)">{{match}}</li>
					</ul>
				</div>
				
				<div class="history">
					<p class="history-title">
						搜索历史
						<span 
							v-show="searchHistory.length" 
							class="history-clear" 
							@click="clearSearchHistory">
							清空
						</span>
					</p>
					<div class="history-list">
						<div v-for="his in searchHistory" :key="his" class="history-tag" @click="searchTag(his)">
							{{his}}
							<UIIcon icon="close" class="history-remove" @click.stop="removeSearchHistory(his)"></UIIcon>
						</div>
					</div>
					<div class="history-empty">暂无记录</div>
				</div>
			</div>
		</transition>
	</div>
</template>

<script>
	
	import { defineComponent, ref, computed, watch, onMounted, unref } from "vue";
	import { useRoute, useRouter } from 'vue-router';
	import useWithin from '@/compositions/useWithin';
	import useSearchHistory from '@/compositions/useSearchHistory';
	import UIIcon from '@/ui/icon';
	import { searchHisLSKey, searchDefinedTags } from '@/constant/searchDefined';
	
	export default defineComponent({
		name: 'BaseSearch',
		components: {
			UIIcon
		},
		props: {
			hideContent: Boolean,
			searchQuery: String
		},
		emits: ['search', 'in', 'out'],
		setup(props, { attrs, slots, emit, expose }) {
			
			const rootElement = ref();
			const searchElement = ref();
			
			const route = useRoute();
			const router = useRouter();
			
			const searchValue = ref(route.query[props.searchQuery]);
			
			const { isWithin } = useWithin(rootElement);
			const { searchHistory, reset: resetSearchHistory, add: addSearchHistory, remove: removeSearchHistory, clear: clearSearchHistory } = useSearchHistory(searchHisLSKey);
			
			const matchedDefinedTags = computed(() => {
				return searchValue.value ? searchDefinedTags.filter(tag => tag.search(searchValue.value) >= 0).slice(0, 10) : [];
			})
			
			watch(isWithin, (newVal) => emit(newVal ? 'in' : 'out'));
			
			onMounted(() => {
				if (searchValue.value) {
					emit('search', searchValue.value);
				}
			})
			
			function searchEnter({ target }) {
				target.value && searchKey(target.value.trim());
			}
			
			function searchTag(value) {
				searchValue.value = value;
				searchKey(value.trim());
			}
			
			function searchKey(value) {
				addSearchHistory(value);
				if (route.name != 'search') {
					router.push({ name: 'search', query: { key: value } });
					searchValue.value = null;
				} else {
					router.replace({ query: { key: value } });
				}
				searchElement.value.blur();
				rootElement.value.blur();
				emit('search', value);
			}
			
			return {
				rootElement, searchElement,
				searchValue, searchHistory,
				isWithin,
				searchEnter, searchTag,
				resetSearchHistory, removeSearchHistory, clearSearchHistory,
				matchedDefinedTags
			}
		}
	})
	
</script>

<style lang="scss" scoped>
	
	.search {
		position: relative;
		padding: 4px 8px;
		background: #f1f2f3;
		border: 1px solid #e3e5e7;
		transition: all .25s;
		border-radius: 4px;
		outline: none;
		box-sizing: border-box;
		&.is-within, &:hover {
			background: #fff;
		}
		&.is-within {
			border-radius: 4px 4px 0 0;
		}
	}
	
	.trigger {
		display: flex;
		align-items: center;
		gap: 10px;
	}
	
	.form {
		flex: 1;
		border-radius: 4px;
	}
	
	.input {
		width: 100%;
		overflow: hidden;
		padding: 0 8px;
		border: none;
		background-color: transparent;
		box-shadow: none;
		color: #676b73;
		font-size: 12px;
		line-height: 20px;
		box-sizing: border-box;
	}
	
	.content {
		position: absolute;
		padding: 10px;
		top: calc(100% - 1px);
		left: -1px;
		right: -1px;
		border-radius: 0 0 4px 4px;
		transition: inherit;
		background: inherit;
		border: inherit;
		border-top: none;
	}
	
	.content-enter-from,
	.content-leave-to {
		opacity: 0;
	}
	
	.match {
		margin-bottom: 10px;
	}
	
	.match-list {
		color: #676b73;
		font-size: 12px;
		max-height: 200px;
		overflow: auto;
	}
	
	.match-item {
		cursor: pointer;
		&:hover {
			color: #66ccff;
		}
		&+& {
			margin-top: 5px;
		}
	}
	
	.history-title, .match-title {
		font-size: 16px;
		margin-bottom: 10px;
		display: flex;
		justify-content: space-between;
		align-items: center;
	}
	
	.history-clear {
		font-size: 12px;
		color: #909399;
		cursor: pointer;
		&:hover {
			color: #f56c6c;
		}
	}
	
	.history-list {
		display: flex;
		gap: 10px;
		flex-wrap: wrap;
		&:empty+.history-empty {
			display: block;
		}
	}
	
	.history-tag {
		padding: 0 12px;
		font-size: 12px;
		border-radius: 10px;
		line-height: 20px;
		border: 1px solid #e3e5e7;
		color: #676b73;
		background: #f4f4f4;
		cursor: pointer;
		position: relative;
		&:hover {
			background: #fff;
			color: #909399;
			.history-remove {
				opacity: 1;
				pointer-events: auto;
			}
		}
	}
	
	.history-remove {
		position: absolute;
		top: 0;
		right: 0;
		transform: translate(33.33%, -33.33%);
		pointer-events: none;
		opacity: 0;
		transition: all .25s;
		&:hover {
			color: #f56c6c;
		}
	}
	
	.history-empty {
		color: #676b73;
		text-align: center;
		display: none;
	}
	
</style>